home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / corewars / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-14  |  4.6 KB  |  218 lines

  1. /*    Copyrighted (C) 1989 by Na Choon Piaw.  All rights reserved       */
  2.  
  3.  
  4.  
  5. /*    This program and documentation is Public Domain, and may be      */
  6. /*    distributed and copied by everyone provided this header          */
  7. /*    remains intact                              */
  8.  
  9. /* parser portion of the assembler.
  10.    11/15/88         - NCP        */
  11.  
  12. #include <strings.h>
  13. #include <stdio.h>
  14. #include "assem.h"
  15.  
  16. /* parser:
  17.   Algorithm:
  18.     1)    initialize symbol table
  19.     2)    Scan first element in token list
  20.     3)    if symbol declaraion (e.g. "start:") then lookup and enter into
  21.         symbol table
  22.     4)    if instruction, skip forward number of parameters
  23.         that instruction accepts
  24.     5)    otherwise error (not instruction or symbol)
  25.     6)    repeat 3-6 until no more tokens.
  26. */
  27. parse(tokens,table)
  28. tokenlist    *tokens;    /* list of tokens */
  29. tag1        table[];    /* symbol table */
  30. {
  31.     int    i = 0;        /* instructon counter */
  32.  
  33.     init(table);        /* initialize table */
  34.  
  35.     while (tokens)
  36.     {
  37.         if (symbol(tokens))
  38.         {
  39.             insert(tokens,table,i);
  40.             tokens = tokens -> next;
  41.         }
  42.         else if (instruction(tokens))
  43.         {
  44.             int    j = 0, k = para(tokens);
  45.  
  46.             /* move up to next instruction:
  47.                i.e., move from instruction + number of parameters
  48.                if instruction is one parameter, move twice, etc */
  49.             while (j <= k)
  50.             {
  51.                 tokens = tokens -> next;
  52.                 j++;
  53.             }
  54.  
  55.             i++;        /* next instruction */
  56.         }
  57.         else            /* not instruction or symbol */
  58.         {
  59.             printf("%s not symbol or instruction\n",
  60.                 tokens -> token);
  61.             printf(" --- parse\n");
  62.             exit(1);
  63.         }
  64.     }    /* while */
  65.  
  66.     /* test for too many instructions */
  67.     if (i > MAXINST)
  68.     {
  69.         printf("too many instructions\n");
  70.         printf("---- parse\n");
  71.         exit(1);
  72.     }
  73. } /* parse */
  74.  
  75. init(table)        /* function to initialize symbol table (set to 0 */
  76. tag1    table[];
  77. {
  78.     int    i;
  79.  
  80.     for (i = 0; i < SYMBOLS; i++)
  81.     {
  82.         table[i].symbol = NULL;
  83.         table[i].position = 0;
  84.     }
  85. }
  86.  
  87. int symbol(tok)
  88. /* identifies a symbol:
  89.     A symbol is just a token that ends with a ':'    */
  90. tokenlist    *tok;
  91. {
  92.     char    *t;        /* token string */
  93.  
  94.     t = tok -> token;
  95.     if ((t[strlen(t) - 1]) == ':')    /* address last character */
  96.         return 1;        /* is symbol declaration */
  97.     else
  98.         return 0;
  99. }
  100.  
  101. /* inserts a token into a symbol table (without stripping the ':') -
  102.    Algorithm:
  103.     1)    search until symbol table reads a NULL string or
  104.         the new symbol is equal to and old one.
  105.     2)    if the new symbol is not a NULL, then error
  106.         otherwise, insert
  107.     3)    if out of space, error
  108. */
  109. int insert(tok, table, no)
  110. tokenlist    *tok;            /* token */
  111. tag1        table[];        /* symbol table */
  112. int        no;            /* instruction number */
  113. {
  114.     char    *t;        /* token string */
  115.     int    i = 0;        /* index on table */
  116.  
  117.     t = tok -> token;
  118.  
  119.     /* search for empty place in table */
  120.     for (; i < SYMBOLS && table[i].symbol != NULL &&
  121.            (strcmp(table[i].symbol,t) != 0); i++)
  122.         ;
  123.  
  124.     if (table[i].symbol != NULL)
  125.     {
  126.         printf("symbol %s already declared\n", t);
  127.         printf("--- insert\n");
  128.         exit(1);
  129.     }
  130.  
  131.     table[i].symbol = t;
  132.     table[i].position = no;
  133. }
  134.  
  135. /* tests whether instruction */
  136. int instruction(tok)
  137. tokenlist    *tok;
  138. {
  139.     char    *t;        /* token string */
  140.  
  141.     t = tok -> token;
  142.     /* note that due to a quirk in strcmp (it returns a zero if the
  143.        strings are equal) this looks particularly convoluted, but
  144.        the logic is simple.                                        */
  145.     return(! (strcmp (t,MOV) && strcmp (t,ADD) && strcmp (t,SUB) &&
  146.           strcmp (t,JMP) && strcmp (t,JMZ) && strcmp (t,JMN) &&
  147.           strcmp (t,DJN) && strcmp (t,CMP) && strcmp (t,SPL) &&
  148.           strcmp (t,DAT)));
  149. }
  150.  
  151. /* return the number of parameters an instruction has */
  152. int para(tok)
  153. tokenlist    *tok;
  154. {
  155.     char    *t;        /* token string */
  156.     int    i = 0;        /* return value */
  157.  
  158.     t = tok -> token;
  159.  
  160.     /* use a multiple if-elseif statement */
  161.     if (!strcmp(t, MOV))
  162.         i = 2;
  163.     else if (!strcmp(t, ADD))
  164.         i = 2;
  165.     else if (!strcmp(t, SUB))
  166.         i = 2;
  167.     else if (!strcmp(t, JMP))
  168.         i = 1;
  169.     else if (!strcmp(t, JMZ))
  170.         i = 2;
  171.     else if (!strcmp(t, JMN))
  172.         i = 2;
  173.     else if (!strcmp(t, DJN))
  174.         i = 2;
  175.     else if (!strcmp(t, CMP))
  176.         i = 2;
  177.     else if (!strcmp(t, SPL))
  178.         i = 1;
  179.     else if (!strcmp(t, DAT))
  180.         i = 1;
  181.     else    /* unrecognized instruction */
  182.     {
  183.         printf("%s is not an instruction\n", t);
  184.         printf("--- para\n");
  185.         exit(1);
  186.     }
  187.  
  188.     return(i);
  189. }    /* para */
  190.  
  191.  
  192.  
  193.  
  194. /* debugging section of parse.c */
  195. /* code commented out --- given a clean bill of health by Dr. Na Choon Piaw
  196.    --- 11/15/88                                                           */
  197. /* declare tokenize */
  198. /* extern tokenlist *tokenize(); */
  199. /* declare symbol table */
  200. /* tag1    table[SYMBOLS]; */
  201.  
  202. /* main(argc,argv)
  203. int    argc;
  204. char    *argv[];
  205. {
  206.     tokenlist    *head;
  207.     FILE        *f;
  208.     int        i;
  209.  
  210.     f = fopen(argv[1], "r");
  211.     head = tokenize(f);
  212.     parse(head, table);
  213.  
  214.     printf("%s\t%s\n", "SYMBOL", "POSITION");
  215.     for (i = 0; table[i].symbol != NULL; i++)
  216.         printf("%s\t%d\n", table[i].symbol, table[i].position);
  217. }  */
  218.